package ev.operator;//need to add this line

import ev.data.*;//need to add this line
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Random;


public class OrderCrossover implements Crossover {

	private int[]aa;
	private int[]bb;
	private ArrayList<Integer> aList;
	private ArrayList<Integer> bList;
	private HashSet<Integer> set;

	public ArrayList<Individual> cross(Individual a, Individual b) {
		this.aa = a.getList();
		this.bb = b.getList();
		for(int i=0; i<aa.length; i++) {
			aList.add(aa[i]);
			bList.add(bb[i]);
		}
		ArrayList<Integer> array = orderCrossover();
		ArrayList<Individual> toReturn = new ArrayList<Individual>();
		int [] toReturnArray = new int[array.size()];
		for(int i = 0; i<array.size(); i++) {
			toReturnArray[i] = array.get(i);
		}
		Individual indi = new Individual(toReturnArray);
		toReturn.add(indi);
		return toReturn;
	}


	public OrderCrossover(){
		aList = new ArrayList<Integer>();
		bList = new ArrayList<Integer>();
		set = new HashSet<Integer>();

	}



	public ArrayList<Integer> orderCrossover() {
		ArrayList<Integer> toReturn = new ArrayList<Integer>();
		for(int i = 0; i<aa.length; i++) {
			toReturn.add(0);
		}
		Random randomGenerator = new Random();
		int i = randomGenerator.nextInt(aa.length);
		int j = randomGenerator.nextInt(aa.length);
		if(i == j) {
			toReturn.set(i, aa[i]);
			set.add(aa[i]);
			int index = (i+1 == aa.length) ? 0 : i + 1;
			for(int k = index; k<aa.length; k++) {
				if(!set.contains(bb[k])) {
					toReturn.set(index++, bb[k]);
					set.add(bb[k]);
				}

				if(index == aa.length) {
					index = 0;
				}
				if(k == aa.length -1) {
					k = -1;
				}
				if(index == i) {
					break;
				}
			}

		} else {
			int start = Math.min(i, j);
			int end = Math.max(i, j);
			for(int k = start; k<=end; k++) {
				toReturn.set(k, aa[k]);
				set.add(aa[k]);
			}
			int index = (end+1 == aa.length) ? 0 : end + 1;
			for(int k = index; k<aa.length; k++) {
				if(!set.contains(bb[k])) {
					toReturn.set(index++, bb[k]);
					set.add(bb[k]);
				}
				if(index == aa.length) {
					index = 0;
				}
				if(k == aa.length -1) {
					k = -1;
				}
				if(index == start) {
					break;
				}
			}
		}
		set.clear();
		return toReturn;
	}
}
